package com.yx.udp.util;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Formatter;

/**
 * 数据转换，采用小端序
 *
 * @author langzhou
 * @date 2023-03-21 14:36
 */
public class DigitalUtils {

    private static Formatter sFormatter = new Formatter();

    /**
     * int转成2子节的byte，只看低16位
     */
    public static byte[] intToBytes(int intNum) {
        byte[] byteArr = new byte[2];
        byteArr[0] = (byte) (intNum & 0xFF);
        byteArr[1] = (byte) (intNum >> 8 & 0xFF);
        return byteArr;
    }

    /**
     * 2子节byte转int
     */
    public static int bytesToInt(byte[] numBytes) {
        int intNum = 0;
        for (int i = 0; i < numBytes.length; i++) {
            intNum += (numBytes[i] & 0xFF) << i * 8;
        }
        return intNum;
    }

    /**
     * int转成4子节的byte
     * @param intNum
     * @return
     */
    public static byte[] intTo4Bytes(int intNum) {
        byte[] byteArr = new byte[4];
        byteArr[0] = (byte) (intNum & 0xFF);
        byteArr[1] = (byte) (intNum >> 8 & 0xFF);
        byteArr[2] = (byte) (intNum >> 16 & 0xFF);
        byteArr[3] = (byte) (intNum >> 24 & 0xFF);
        return byteArr;
    }

    public static int bytesToIntWithByteBuffer(byte[] numBytes) {
        return ByteBuffer.wrap(numBytes)
                .order(ByteOrder.LITTLE_ENDIAN)
                .getInt();
    }

    public static byte[] intToBytesWithByteBuffer(int numInt) {
        return ByteBuffer.allocate(4)
                .order(ByteOrder.LITTLE_ENDIAN)
                .putInt(numInt)
                .array();
    }

    public static byte[] longToBytes(long longNum) {
        return ByteBuffer.allocate(8)
                .order(ByteOrder.LITTLE_ENDIAN)
                .putLong(longNum)
                .array();
    }

    public static long bytesToLong(byte[] numBytes) {
        return ByteBuffer.wrap(numBytes)
                .order(ByteOrder.LITTLE_ENDIAN)
                .getLong();
    }

    public static byte[] floatToBytes(float floatNum) {
        byte[] floatBytes = new byte[4];
        int floatBits = Float.floatToIntBits(floatNum);

        // 小端序，最低有效字节放在数组的第一个位置
        floatBytes[0] = (byte) floatBits;
        floatBytes[1] = (byte) (floatBits >> 8);
        floatBytes[2] = (byte) (floatBits >> 16);
        floatBytes[3] = (byte) (floatBits >> 24);
        return floatBytes;
    }

    public static float bytesToFloat(byte[] bytes) {
        if (bytes == null || bytes.length != 4) {
            return 0;
        }

        int intBits = (bytes[0] & 0xFF)
                | ((bytes[1] & 0xFF) << 8)
                | ((bytes[2] & 0xFF) << 16)
                | ((bytes[3] & 0xFF) << 24);
        return Float.intBitsToFloat(intBits);
    }

    /**
     * 1字节转十六进制字符串
     */
    public static String byteToHex(byte b) {
        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() < 2) {
            hex = "0" + hex;
        }
        return hex.toUpperCase();
    }

    public static String bytesToString(byte[] bytes) {
        if (bytes == null) {
            return "";
        }

        int endCharIndex = bytes.length;
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] == 0) {
                endCharIndex = i;
                break;
            }
        }

        return new String(bytes, 0, endCharIndex);
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }

    public static String bytesToHex(byte[] bytes, int startIndex, int endIndex) {
        if (bytes == null || startIndex < 0 || endIndex < 0 || startIndex > endIndex
                || startIndex > bytes.length - 1
                || endIndex > bytes.length - 1) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        for (int i = startIndex; i < endIndex; i++) {
            sb.append(String.format("%02X ", bytes[i]));
        }
        return sb.toString().trim();
    }

    public static String intsToHex(int[] ints) {
        StringBuilder sb = new StringBuilder();
        for (int i : ints) {
            sb.append(String.format("%02X ", (byte) i));
        }
        return sb.toString().trim();
    }

    /**
     * 版本比较，参数必须严格按照x.x传入
     *
     * @param mine  己身版本
     * @param other 被比对版本
     * @return mine > other返回正数，mine = other返回0，mine < other返回负数
     */
    public static int compareVersion(String mine, String other) {
        if (mine == null || other == null) {
            // 任何一方为空，默认当前版本大
            return 1;
        }

        if (mine.length() != other.length()) {
            // 长度不等，默认当前版本大
            return 1;
        }

        String[] mineSplit = mine.split("\\.");
        String[] otherSplit = other.split("\\.");
        for (int i = 0; i < mineSplit.length; i++) {
            int mineValue = Integer.parseInt(mineSplit[i]);
            int otherValue = Integer.parseInt(otherSplit[i]);
            if (mineValue > otherValue) {
                return 1;
            }
            if (mineValue < otherValue) {
                return -1;
            }
        }

        return 0;
    }

    public static String intToBinaryString(int number) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            sb.append((number & 0x80000000) == 0 ? '0' : '1');
            number <<= 1;
        }
        return sb.toString();
    }

    public static String byteToBinaryString(byte b) {
        return String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
    }

}
